/**
 * @description XTip
 */

(function(XTip){

	// set defalut config
	var config = {
		action:'hover',		//触发动作，hover,click,once
		show:false,
		tipProp:'title',	//内容属性
		addTipStyle:null,	//是否填出tip触发样式
		autoClose:null,		//是否自动关闭
		delayClose:null,	//延迟关闭时间
		target:null,		//内容目标
		url:null,			//ajax请求页面地址
		child:null,			//子项触发选择器
		width:200,			
		height:null,
		content:null,		//内容
		container:null,		//容器
		fnBoforeClose:null,
		fnClose:null,
		global:false,		//是否生成在主页面body里
		offset:false,		//对于域内元素的相对offset ,默认false
		showOverflow:false  //内容超出的时候显示
//		,position:'cursor'
	};
	
	//define control flow
	var flow = {
		init:function(tip , op){
            tipHelper.Init(tip , op);
		},
		build:function(tip , op){
		    //tipHelper.Build(tip , op);
		},
		bindEvent:function(tip , op){
		    tipHelper.EventBinder.Init(tip , op);
		}
	};
	
	//define control manager
	var manager = {
		getTip:function(){
			this.op._tip || ( this.op._tip = this.createTip(this , this.op) );
			return this.op._tip;
		},
		showTip:function(content,target){
			var me = this,target = target || me.dom ,op = me.op;
			op._show = true;
			var tip = me.getTip();
			if (tip && tip.length) {
				if (content != null) {
					this.setContent(content);
				} else if (op.url) {
					// setContentByUrl
					this.getTipBody(tip).loading(0, 1).load(op.url,
							function() {
								tip.loadingClose();
								me.popup(target, tip);
							});
					op.url = null;
					return tip;
				}
				if (target.is(":visible") && (content == null || content)){
					me.popup(target, tip);
				}else{
					me.closeTip();
				}
			}
			return tip;
		},
		showTipByAuto:function(target){
			var content = target.attr(this.op.tipProp);
			if(!content){
				if(target.text()){
					content = target.html();
				}else{
					//没有数据则不弹出tip
					this.closeTip();
					return;
				}
				if(this.op.showOverflow){
					if(typeof this.op.showOverflow == "function"){
						if(this.op.showOverflow(target)){
							this.closeTip();
							return;
						}
					}else{
					var showOverflow = $('<div style="float:left;height:0px;"></div>').css({
						"font-size":target.css("font-size")
					}).html(content).appendTo($(document.body));
					if(showOverflow.width()<=target.width()){
						showOverflow.remove();
						//内容不超出则不弹出tip
						this.closeTip();
						return;
					}
					showOverflow.remove();
					}
				}
			}
			this.showTip(content,target);
		},
		closeTip:function(delay){
			var op = this.op;
			if(op._show){
				var self = this;
				if(!op.fnBeforeClose || op.fnfnBeforeClose.call(self) !== false){
					op._show = false;
					delay == null && (delay = op.delayClose);
					if(delay) {
						var self = this;
						setTimeout(function(){
							self.getTip().hide();
							op.fnClose && op.fnClose.call(self);
						},delay);
					}
					else {
						this.getTip().hide();
						op.fnClose && op.fnClose.call(self);
					}
				}
			}
		},
		setContent:function(content){
			this.getTipBody(this.getTip()).html(content);
		},
		getTipBody:function(tip){
			return tip.children('.ccay-tip-content');
		},
		createTip:function(tip , op){
			var id = '_tip_' + (typeof this.id == "undefined" ? "content" : this.id);
			$("#"+id).remove();
			var createTip =  $.create('div','ccay-tip',id);
			if(op.global){
				$("body").prepend(createTip.addClass("global")); 
			} else if(op.container){
				createTip.appendTo(op.container);
			} else {
				createTip.insertAfter(this.dom);
			};
			createTip.html("<div class='ccay-tip-arrow' ></div><div class='ccay-tip-content' ></div>");
			
			createTip.width(op.width).height(op.height);
			
			op.action == 'hover' && Ccay.UI.bindPopupHover(createTip,null,function(){
				setTimeout(function(){
					!createTip.data('_inpop') && tip.closeTip();
				},100);
			});
			
			var contentPanel = this.getTipBody(createTip).width(op.width - 19).height(op.height);
			//判断是否内置目标对象
			if(!op.child) {
				if(op.content){
					contentPanel.html(op.content);
					op.content = null;
				} else if(op.target){
					contentPanel.append($(op.target).show());
				}
			}
			return createTip;
		},
		popup:function(target, tip){
			// 目标存在的时候，才tip
			if (target.length) {
				tip || (tip = this.getTip());
				var op = this.op, offset = op.global || op.offset;
				if(offset && op.position == 'cursor' && op._e)
				{
					tip.css({left:op._e.pageX,top:op._e.pageY,position:"absolute"}).show();
				}
				else
					Ccay.UI.popup(target,tip,this.getPosition(target,tip),true,offset);
				op._e = null;
			}
		},
		getPosition:function(target,tip){
			var pos = target.offset(),
			    winWidth = $(window).width(),
				tipWidth = tip.outerWidth(),
				left,
				triggerWidth = target.outerWidth();
			// 非global下，如果tip在dialog中,修改winWidth,pos.left
			if(!this.op.global){
				var inDialog = target.parents(".ccay-dialog:first");
				if(inDialog.length){
					winWidth = inDialog.width();
					pos.left = pos.left - inDialog.offset().left;
				};
			};
			if(pos.left + tipWidth + triggerWidth > winWidth){
				left = - tipWidth - 5;
				tip.addClass('ccay-tip-left');
			}else{
				left = triggerWidth + 5;
				tip.removeClass('ccay-tip-left');
			}
			return {left:left};
		},
		unbind:function(){
			this.getTip().remove();
			this.dom.removeData('XTip_op');
			this.dom.unbind(this.op.action == 'click' ? 'click.tip' : 'mouseenter.tip mouseleave.tip');
			this.op = this.ctr = null;
		}
	};
	
	//define inner functions
	var tipHelper = {
		Init:function(tip , op){
			op.addTipStyle !== false && op.action != "once" && tip.dom.addClass('ccay-tip-trigger');
			if(!op.child && !op.content){
				if(!(op.url = tip.dom.attr('url'))){
					if(!(op.target = tip.dom.attr('target'))){
						op.content = tip.dom.attr(op.tipProp);
						tip.dom.removeAttr(op.tipProp);
					}
				}
			}
			tip.dom.removeAttr('title');
		},
		getTipObj:function(trigger){
			return $(trigger).manager("XTip");
		},
		EventBinder:{
			Init : function(tip , op){
				op.child ? this.bindTargetEvent(tip,op) : this.bindEvent(tip,op);
			},
			bindEvent : function(tip,op){
				if(op.action == 'click'){
					tip.dom.unbind("click.tip").bind("click.tip",function(e){
						if(tip){
							if(tip.op._show)
								tip.closeTip() 
							else
							{
								tip.op._e = e;
								tip.showTip();
							}
						}
					});
				} 
				else if(op.action == 'once'){
					var sTip = tip.showTip(); 
					sTip.click(function(){
						tip.closeTip(0);
					});
					op.autoClose && tip.closeTip(op.delayClose || 4000);
				}
				else{
					var action,isclose,timeout,
						fnHover = function(e,tip){
							
							return setTimeout(function () { 
								if(action){
									tip.op._e = e;
									tip.showTip(); 
									isclose = true;
									timeout = null
								}
								else if(isclose){
									if(!tip.getTip().data('_inpop')){
										tip.closeTip();
										isclose = false;
									}
								}
							}, 100);
						};
					
					tip.dom.unbind("mouseenter.tip mouseleave.tip").bind("mouseenter.tip",function(e){
						action = true;
						timeout && clearTimeout(timeout);
						timeout = fnHover(e,tip);
					}).bind("mouseleave.tip",function(e){
						action = false;
						if(!timeout)
							timeout = fnHover(e,tip);
					});
					
//					tip.dom.hover(function(){
//						action = true;
//						timeout && clearTimeout(timeout);
//						timeout = fnHover(tip);
//					},function(trigger,op){
//						action = false;
//						if(!timeout)
//							timeout = fnHover(tip);
//					})
				}
				if(op.action != 'once' && op.show){
					var sTip = tip.showTip(); 
					sTip.click(function(){
						tip.closeTip(0);
					});
				}
			},
			bindTargetEvent : function(tip,op){
				if(op.action == 'click')
				{
					tip.dom.delegate(op.child,"click.tip",function(e){
						var target = $(this);
						if(tip.op._show)
							tip.closeTip() 
						else
						{
							tip.op._e = e;
							tip.showTipByAuto(target);
						}
					})
				}
				else
				{
					var action,isclose,timeout,
						fnHover = function(e,tip,target){
							return setTimeout(function () { 
								if(action){
									tip.op._e = e;
									tip.showTipByAuto(target); 
									isclose = true;
									timeout = null
								}
								else if(isclose){
									if(!tip.getTip().data('_inpop'))
									{
										tip.closeTip();
										isclose = false;
									}
								}
							}, 100);
						};
					tip.dom.delegate(op.child,"mouseover",function(e){
							action = true;
							timeout && clearTimeout(timeout);
							timeout = fnHover(e,tipHelper.getTipObj(e.delegateTarget),$(this));
						}).delegate(op.child,"mouseout",function(e){
							action = false;
							if(!timeout)
								timeout = fnHover(e,tipHelper.getTipObj(e.delegateTarget),$(this));
						});
				}
			}
		}	
	};
	
	//create XControl
	var XTip = Ccay.UI.XControl("XTip",flow,config,manager);
	
	// create jquery plugin
	$.fn.tip = function(op){
		return this.each(function(){
			new XTip ($(this), op);
		})
	};
	
	// create tip 
	$.fn.ccayTip = function(op) {
		if ($.isPlainObject(op)){
			if(op.content){
				op.content = $i18n(op.content);
			}	
			return this.tip(op);
		} else {
			return this.tip({content : $i18n(op)});
		}
	};
	
	// close tip
	$.fn.ccayRemoveTip = function() {
		return this.manager('XTip').closeTip();
	};
	
})(Ccay.UI.XTip);


